বিশ্বাস করুন বা না করুন, এনক্রিপ্ট করা ডেটা দিয়ে গণনা করা সম্ভব। অন্য কথায়, একটি প্রোগ্রাম চালানো সম্ভব যেখানে প্রোগ্রামের সমস্ত ভেরিয়েবল এনক্রিপ্টেড
এই টিউটোরিয়ালে, আমরা এনক্রিপ্ট করা গণনার খুব প্রাথমিক সরঞ্জামগুলি দেখবো। বিশেষত, আমরা Secure Multi-Party Computation নামে পরিচিত একটি জনপ্রিয় পদ্ধতির উপর ফোকাস করতে যাচ্ছি। এই পাঠে, আমরা শিখব কীভাবে একটি এনক্রিপ্ট করা ক্যালকুলেটর তৈরি করতে হয়, যা এনক্রিপ্ট হওয়া সংখ্যায় গণনা সম্পাদন করতে পারে।
Authors:
References:
অনুবাদক:
এসএমপিসি(SMPC) প্রথম নজরে "এনক্রিপশন" এর এক অদ্ভুত রূপ। কোনও ভেরিয়েবল এনক্রিপ্ট করার জন্য পাবলিক/প্রাইভেট চাবি(key) ব্যবহার করার পরিবর্তে প্রতিটি মান একাধিক shares-এ বিভক্ত হয়, যার প্রতিটি একটি ব্যক্তিগত চাবি(key) হিসাবে চালিত হয়। সাধারণত, এই shares ২ বা ততোধিক মালিকদের মাঝে বিতরণ করা হবে। সুতরাং, সমস্ত মালিকদের ডিক্রিপশন অনুমোদনের সম্মতির সাপেক্ষে ভেরিয়েবলটি ডিক্রিপ্ট(decrypt) করা হবে। সংক্ষেপে, প্রত্যেকের একটি ব্যক্তিগত চাবি আছে।
সুতরাং, ধরা যাক আমরা একটি ভেরিয়েবল x
"এনক্রিপ্ট" করতে চেয়েছিলাম, আমরা নিম্নলিখিত পদ্ধতিতে এটি করতে পারি।
এনক্রিপশন ফ্লোটস বা বাস্তব সংখ্যা ব্যবহার করে না তবে এটি integer quotient ring নামক গাণিতিক স্পেসে ঘটে যা মূলত
0
এবংQ-1
এর মধ্যে বিদ্যমান পূর্ণসংখ্যা। যেখানেQ
মৌলিক এবং "যথেষ্ট বড়" যেন স্পেসটি আমাদের পরীক্ষাগুলিতে আমরা যে সমস্ত সংখ্যা ব্যবহার করি তা ধারণ করতে পারে। বাস্তবে, একটি পূর্ণসংখ্যা মানx
দেয়া হলে, আমরাx % Q
করি যেন তা রিং এর মধ্যে ফিট করে। (এজন্যই আমরাx' > Q
সংখ্যা ব্যবহার করা এড়িয়ে চলি ).
In [0]:
Q = 1234567891011
In [0]:
x = 25
In [0]:
import random
def encrypt(x):
share_a = random.randint(-Q,Q)
share_b = random.randint(-Q,Q)
share_c = (x - share_a - share_b) % Q
return (share_a, share_b, share_c)
In [0]:
encrypt(x)
Out[0]:
In [0]:
def decrypt(*shares):
return sum(shares) % Q
In [0]:
a,b,c = encrypt(25)
In [0]:
decrypt(a, b, c)
Out[0]:
গুরুত্বপূর্ণভাবে লক্ষ করুন যে আমরা যদি মাত্র দুটি শেয়ার দিয়ে ডিক্রিপ্ট করার চেষ্টা করি তবে ডিক্রিপশনটি কার্যকর হয় না!
In [0]:
decrypt(a, b)
Out[0]:
সুতরাং, মানটি ডিক্রিপ্ট করার জন্য আমাদের সকল মালিকদের অংশ নেওয়া প্রয়োজন। এটি এইভাবে shares
ব্যক্তিগত চাবির মতো কাজ করে, মানটি ডিক্রিপ্ট করার জন্য অবশ্যই এগুলির সবগুলোর উপস্থিতি থাকতে হবে।
In [0]:
x = encrypt(25)
y = encrypt(5)
In [0]:
def add(x, y):
z = list()
# the first worker adds their shares together
z.append((x[0] + y[0]) % Q)
# the second worker adds their shares together
z.append((x[1] + y[1]) % Q)
# the third worker adds their shares together
z.append((x[2] + y[2]) % Q)
return z
In [0]:
decrypt(*add(x,y))
Out[0]:
এবং আপনি এটা পেয়ে গেলেন! যদি প্রতিটি কর্মী (পৃথকভাবে) তাদের শেয়ারগুলি একসাথে যোগ করে, তবে ফলস্বরূপ শেয়ারগুলি সঠিক মানটিতে ডিক্রিপ্ট হবে (25 + 5 == 30).
দেখা যাচ্ছে যে এসএমপিসি(SMPC) প্রোটোকল রয়েছে যা নিম্নলিখিত ক্রিয়াকলাপগুলির জন্য এই এনক্রিপ্ট করা গণনার অনুমতি দিতে পারে:
এবং এই প্রাথমিক অন্তর্নিহিত প্রিমিটিভস ব্যবহার করে, আমরা অবাধে গণনা সম্পাদন করতে পারি !!!
পরবর্তী বিভাগে, আমরা কীভাবে এই অপারেশনগুলি সম্পাদন করতে Pysyft লাইব্রেরি ব্যবহার করতে পারি তা শিখতে চলেছি!
পূর্ববর্তী বিভাগগুলিতে, আমরা এসএমপিসি কিভাবে কাজ করে সে নিয়ে কিছু বেসিক ধারণার রূপরেখা তৈরি করেছি । যাইহোক, বাস্তবে আমাদের এনক্রিপ্ট করা প্রোগ্রামগুলি লেখার সময় আমরা প্রিমিটিভ ক্রিয়াকলাপগুলির সমস্ত কিছু নিজের হাতে লিখতে চাই না। সুতরাং, এই বিভাগে আমরা পাইসাইফ্ট ব্যবহার করে এনক্রিপ্ট করা গণনা কীভাবে করতে হবে তার মূল বিষয়গুলি নিয়ে দেখবো। বিশেষত, আমরা পূর্বে উল্লিখিত ৩-টি প্রিমিটিভ কীভাবে করব তার উপর ফোকাস করতে যাচ্ছি: সংযোজন, গুণ এবং তুলনা।
প্রথমত, আমাদের কয়েকটি ভার্চুয়াল ওয়ার্কার তৈরি করতে হবে (যা আশা করি আপনি এখন আমাদের আগের টিউটোরিয়ালগুলির সাথে পরিচিত আছেন)।
In [0]:
import torch
import syft as sy
hook = sy.TorchHook(torch)
bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
bill = sy.VirtualWorker(hook, id="bill")
In [0]:
x = torch.tensor([25])
In [0]:
x
Out[0]:
In [0]:
encrypted_x = x.share(bob, alice, bill)
In [0]:
encrypted_x.get()
Out[0]:
In [0]:
list(bob._tensors.values())
Out[0]:
In [0]:
x = torch.tensor([25]).share(bob, alice, bill)
In [0]:
# Bob's share
bobs_share = list(bob._tensors.values())[0]
bobs_share
Out[0]:
In [0]:
# Alice's share
alices_share = list(alice._tensors.values())[0]
alices_share
Out[0]:
In [0]:
# Bill's share
bills_share = list(bill._tensors.values())[0]
bills_share
Out[0]:
এবং যদি আমরা চাইতাম, আমরা আগে যে বিষয়গুলি নিয়ে আলোচনা করেছি সেগুলি ব্যবহার করে আমরা এই মানগুলি ডিক্রিপ্ট করতে পারি !!!
In [0]:
(bobs_share + alices_share + bills_share)
Out[0]:
যেমন আপনি দেখতে পাচ্ছেন, আমরা যখন ফোন করেছি.share()
এটি কেবলমাত্র 3 টি শেয়ারে মূল্য বিভক্ত করে এবং প্রতিটি দলের কাছে একটি ভাগ প্রেরণ করে!
In [0]:
x = torch.tensor([25]).share(bob,alice)
y = torch.tensor([5]).share(bob,alice)
In [0]:
z = x + y
z.get()
Out[0]:
In [0]:
z = x - y
z.get()
Out[0]:
গুণনের জন্য আমাদের একটি অতিরিক্ত দল দরকার যারা ধারাবাহিকভাবে র্যান্ডম সংখ্যা তৈরি করার জন্য দায়ী (এবং অন্য দলের কোনটির সাথে মিলিত না হয়ে)। আমরা এই ব্যক্তিকে "ক্রিপ্টো সরবরাহকারী/crypto provider" বলি। সকল নিবিড় উদ্দেশ্যে, ক্রিপ্টো সরবরাহকারী কেবল একটি অতিরিক্ত ভার্চুয়াল ওয়ার্কার, তবে এটি স্বীকার করা জরুরী যে ক্রিপ্টো সরবরাহকারী কোনও "মালিক" নয় যার জন্য তার নিজের অংশীদারি নেই। তবে সে এমন কেউ যাকে বিশ্বাস করতে হবে যেন সে অন্য কোন শেয়ারহোল্ডারের সাথে মিশে না যায়।
In [0]:
crypto_provider = sy.VirtualWorker(hook, id="crypto_provider")
In [0]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)
In [0]:
# multiplication
z = x * y
z.get()
Out[0]:
আপনি ম্যাট্রিক্স গুণও করতে পারেন
In [0]:
x = torch.tensor([[1, 2],[3,4]]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([[2, 0],[0,2]]).share(bob,alice, crypto_provider=crypto_provider)
In [0]:
# matrix multiplication
z = x.mm(y)
z.get()
Out[0]:
প্রাইভেট ভ্যালুগুলোর মধ্যে প্রাইভেট তুলনা করাও সম্ভব। আমরা এখানে SecureNN প্রোটোকলে নির্ভর করি, যার বিবরণ পাওয়া যাবে এখানে। তুলনার ফলাফলটি একটি ব্যক্তিগত শেয়ারড টেনসরও।
In [0]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)
In [0]:
z = x > y
z.get()
Out[0]:
In [0]:
z = x <= y
z.get()
Out[0]:
In [0]:
z = x == y
z.get()
Out[0]:
In [0]:
z = x == y + 20
z.get()
Out[0]:
আপনি max অপারেশনও করতে পারেন
In [0]:
x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)
x.max().get()
Out[0]:
In [0]:
x = torch.tensor([[2, 3], [4, 1]]).share(bob,alice, crypto_provider=crypto_provider)
max_values, max_ids = x.max(dim=0)
max_values.get()
Out[0]:
এই নোটবুক টিউটোরিয়ালটি সম্পন্ন করার জন্য অভিনন্দন। আপনি যদি এটি উপভোগ করেন এবং গোপনীয়তা সংরক্ষণ, AI এবং AI সরবরাহ চেইনের (ডেটা) বিকেন্দ্রীভূত মালিকানার দিকে আন্দোলনে যোগ দিতে চান, আপনি নিম্নলিখিত উপায়ে এটি করতে পারেন।
আমাদের সম্প্রদায়কে সাহায্য করার সবচেয়ে সহজ উপায় হল রিপোসিটোরি গুলোতে ষ্টার করা এটি আমরা যে অসাধারণ সরঞ্জামগুলি তৈরি করছি তার সচেতনতা বাড়াতে সহায়তা করে।
সর্বশেষতম অগ্রগতিতে আপ টু ডেট রাখার সর্বোত্তম উপায় হ'ল আমাদের সম্প্রদায়ে যোগদান করা। আপনি ফর্মটি পূরণ করে এটি করতে পারেন http://slack.openmined.org
আমাদের সম্প্রদায়ে অবদান রাখার সর্বোত্তম উপায় হল কোড অবদানকারী হয়ে উঠুন! যে কোনও সময় আপনি পাইসাইফ্ট গিটহাবে ইস্যু পৃষ্ঠাতে যেতে পারেন এবং "প্রকল্পগুলি" এর জন্য ফিল্টার করতে পারেন। এটি আপনাকে শীর্ষ স্তরের সমস্ত টিকিট দেখিয়ে দেবে যে আপনি কোন প্রকল্পগুলিতে যোগদান করতে পারেন তার একটি ওভারভিউ দেয়! আপনি যদি কোনও প্রকল্পে যোগ দিতে না চান তবে আপনি কিছুটা কোডিং করতে চান তবে আপনি "ভাল প্রথম ইস্যু" চিহ্নিত গিথুব ইস্যুগুলি অনুসন্ধান করে আরও "ওয়ান অফ" মিনি-প্রকল্পগুলির সন্ধান করতে পারেন।
আপনার যদি আমাদের কোডবেসে অবদান রাখার সময় না থাকে তবে তবুও সমর্থন দিতে চান, আপনি আমাদের ওপেন কালেক্টিভেরও Backer হয়ে উঠতে পারেন। সমস্ত অনুদান আমাদের ওয়েব হোস্টিং এবং অন্যান্য সম্প্রদায় ব্যয় যেমন হ্যাকাথন এবং মিটাপগুলির (hackathons and meetups!) দিকে যায়।
In [0]: